﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace FullScreen
{
    public  class FullScreenControler
    {
        #region DllImports
        /// <summary>
        /// FindWindow will find a window by specifying the WndClass or the Caption
        /// </summary>
        /// <param name="lpClassName"></param>
        /// <param name="lpWindowName"></param>
        /// <returns>an intPtr to the found window or null, if not found</returns>
        [DllImport("coredll.dll")]
        extern private static IntPtr FindWindowW(string lpClassName, string lpWindowName);

        /// <summary>
        /// we need this to get the size of the screen
        /// </summary>
        /// <param name="nIndex"></param>
        /// <returns></returns>
        [DllImport("coredll.dll")]
        extern private static int GetSystemMetrics(int nIndex);
        /// <summary>
        /// the used nIndex values for screen ScrWidth and height
        /// </summary>
        private const int SM_CXSCREEN = 0;
        private const int SM_CYSCREEN = 1;

        /// <summary>
        /// query a window for his state
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns>true if window is visible</returns>
        [DllImport("coredll.dll")]
        static extern bool IsWindowVisible(IntPtr hWnd);

        /// <summary>
        /// function to modify the window state of a window
        /// </summary>
        /// <param name="hWnd">handle to the window</param>
        /// <param name="nCmdShow">the required window state</param>
        /// <returns></returns>
        [DllImport("coredll.dll")]
        static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);

        //[DllImport("coredll.dll")]
        //extern public static int GetWindowRect(IntPtr hWnd, ref RECT lpRect);

        //[StructLayout(LayoutKind.Sequential)]
        //public struct RECT
        //{
        //    public int left;
        //    public int top;
        //    public int right;
        //    public int bottom;
        //}
        #endregion

        #region WStyles
        /// <summary>Enumeration of the different ways of showing a window using
        /// ShowWindow</summary>
        private enum WindowShowStyle : uint
        {
            /// <summary>Hides the window and activates another window.</summary>
            /// <remarks>See SW_HIDE</remarks>
            Hide = 0,
            /// <summary>Activates and displays a window. If the window is minimized
            /// or maximized, the system restores it to its original size and
            /// position. An application should specify this flag when displaying
            /// the window for the first time.</summary>
            /// <remarks>See SW_SHOWNORMAL</remarks>
            ShowNormal = 1,
            /// <summary>Activates the window and displays it as a minimized window.</summary>
            /// <remarks>See SW_SHOWMINIMIZED</remarks>
            ShowMinimized = 2,
            /// <summary>Activates the window and displays it as a maximized window.</summary>
            /// <remarks>See SW_SHOWMAXIMIZED</remarks>
            ShowMaximized = 3,
            /// <summary>Maximizes the specified window.</summary>
            /// <remarks>See SW_MAXIMIZE</remarks>
            Maximize = 3,
            /// <summary>Displays a window in its most recent size and position.
            /// This value is similar to "ShowNormal", except the window is not
            /// actived.</summary>
            /// <remarks>See SW_SHOWNOACTIVATE</remarks>
            ShowNormalNoActivate = 4,
            /// <summary>Activates the window and displays it in its current size
            /// and position.</summary>
            /// <remarks>See SW_SHOW</remarks>
            Show = 5,
            /// <summary>Minimizes the specified window and activates the next
            /// top-level window in the Z order.</summary>
            /// <remarks>See SW_MINIMIZE</remarks>
            Minimize = 6,
            /// <summary>Displays the window as a minimized window. This value is
            /// similar to "ShowMinimized", except the window is not activated.</summary>
            /// <remarks>See SW_SHOWMINNOACTIVE</remarks>
            ShowMinNoActivate = 7,
            /// <summary>Displays the window in its current size and position. This
            /// value is similar to "Show", except the window is not activated.</summary>
            /// <remarks>See SW_SHOWNA</remarks>
            ShowNoActivate = 8,
            /// <summary>Activates and displays the window. If the window is
            /// minimized or maximized, the system restores it to its original size
            /// and position. An application should specify this flag when restoring
            /// a minimized window.</summary>
            /// <remarks>See SW_RESTORE</remarks>
            Restore = 9,
            /// <summary>Sets the show state based on the SW_ value specified in the
            /// STARTUPINFO structure passed to the CreateProcess function by the
            /// program that started the application.</summary>
            /// <remarks>See SW_SHOWDEFAULT</remarks>
            ShowDefault = 10,
            /// <summary>Windows 2000/XP: Minimizes a window, even if the thread
            /// that owns the window is hung. This flag should only be used when
            /// minimizing windows from a different thread.</summary>
            /// <remarks>See SW_FORCEMINIMIZE</remarks>
            ForceMinimized = 11
        }
        #endregion
        #region private vars
        private int m_width = 240;
        private int m_height = 320;
        private bool m_SIP_shown = false;

        #endregion
        /// <summary>
        /// class instantiation
        /// store the screen size
        /// </summary>
        public FullScreenControler()
        {
            m_width = GetSystemMetrics(SM_CXSCREEN);
            m_height = GetSystemMetrics(SM_CYSCREEN);
        }

        /// <summary>
        /// public vars to get the screen size
        /// </summary>
        public int ScrWidth
        {
            get
            {
                return m_width;
            }
        }
        public int ScrHeight
        {
            get
            {
                return m_height;
            }
        }
        /// <summary>
        /// will enlarge the form to cover the full screen
        /// the taskbar will be hidden
        /// the SIP will be hidden
        /// </summary>
        /// <param name="f">the form to make fullscreen</param>
        public void makeFullScreen(System.Windows.Forms.Form f)
        {
            f.Width = m_width;
            f.Height = m_height;
            f.Top = 0; f.Left = 0; // move the form to upper left
            hideTaskBar(true); //hide the taskbar
            showSIP(false); //hide the SIP window, regardless of it is shown or not
        }

        /// <summary>
        /// restore previous screen settings
        /// </summary>
        public void Unload()
        {
            hideTaskBar(false);
            if (m_SIP_shown)
                showSIP(true);
            else
                showSIP(false);
        }

        /// <summary>
        /// Hide or show the SIP
        /// </summary>
        /// <param name="bShow"></param>
        private void showSIP(bool bShow)
        {
            //Find SipWndClass
            IntPtr hWndSipWndClass = IntPtr.Zero;
            hWndSipWndClass = FindWindowW("SipWndClass", null);
            if (hWndSipWndClass != IntPtr.Zero)
            {
                if (bShow)
                    ShowWindow(hWndSipWndClass, (uint)WindowShowStyle.ShowNormal);
                else
                    ShowWindow(hWndSipWndClass, (uint)WindowShowStyle.Minimize);
            }
        }

        /// <summary>
        /// Hide or show the TaskBar
        /// </summary>
        /// <param name="mode"></param>
        /// <returns></returns>
        private int hideTaskBar(bool mode)
        {
            IntPtr hWndTaskBar = IntPtr.Zero;
            if (mode)
            {
                hWndTaskBar = FindWindowW("HHTaskBar", null);
                if (hWndTaskBar != IntPtr.Zero)
                {
                    ShowWindow(hWndTaskBar, (uint)WindowShowStyle.Hide);
                }
            }
            else
            {
                hWndTaskBar = FindWindowW("HHTaskBar", null);
                if (hWndTaskBar != IntPtr.Zero)
                    ShowWindow(hWndTaskBar, (uint)WindowShowStyle.ShowNormal);
            }
            return 0;
        }
    }
}
